﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CheccCoverplateCulvertAssemble.Common
{
    public class CalculateCulvertLength
    {
        /// <summary>
        /// 求各涵长集合的方法
        /// </summary>
        /// <param name="totalCulvertLength">总涵长</param>
        /// <param name="obliqueCulminationLengthMinValue">斜涵长最小值</param>
        /// <param name="obliqueCulminationLengthRecommendValue">斜涵长推荐值</param>
        /// <param name="positiveBodyMinValue">正涵身最小值</param>
        /// <param name="positiveBodyMaxValue">正涵身最大值</param>
        /// <returns></returns>
        internal List<double> askCulvertLengthList(double totalCulvertLength, double leftObliqueCulminationLengthMinValue, double leftObliqueCulminationLengthRecommendValue, double rightObliqueCulminationLengthMinValue, double rightObliqueCulminationLengthRecommendValue, double positiveBodyMinValue, double positiveBodyMaxValue)
        {
            //定义一个接受各个涵长值的集合
            List<double> culvertLengthList = new List<double>();

            //定义一个斜涵长和正涵身长度
            double obliqueCulminationLength, positiveBodyLength;

            //定义正涵身的总长度
            double positiveBodyTotalLength;

            //判断涵长减去斜涵长的推荐值是否小于正涵身最小值，决定后续使用斜涵长的最小值还是推荐值
            if (totalCulvertLength - (leftObliqueCulminationLengthRecommendValue + rightObliqueCulminationLengthRecommendValue) < positiveBodyMinValue)
            {
                //判断涵长减去斜涵长最小值是否小于正涵身最小值
                if (totalCulvertLength - (leftObliqueCulminationLengthMinValue + rightObliqueCulminationLengthMinValue) < positiveBodyMinValue)
                {
                    //此时没有正涵身，所以用总涵长求两个斜涵长的值
                    obliqueCulminationLength = totalCulvertLength / 2;

                    //将两个斜涵长添加到集合中进行返回
                    culvertLengthList.Add(obliqueCulminationLength);
                    culvertLengthList.Add(obliqueCulminationLength);
                    return culvertLengthList;
                }
                else
                {
                    //求出正涵身的总长度
                    positiveBodyTotalLength = totalCulvertLength - (leftObliqueCulminationLengthMinValue + rightObliqueCulminationLengthMinValue);

                    //定义正涵身的个数变量
                    int positiveBodyCount = (int)(positiveBodyTotalLength / positiveBodyMinValue);

                    //判断正涵身的个数是否只有一个
                    if (positiveBodyCount == 1)
                    {
                        //判断正涵身按最小正涵身值算时多余长度是否够按最大正涵身长度计算
                        if (positiveBodyTotalLength % positiveBodyMinValue > (positiveBodyMaxValue - positiveBodyMinValue))
                        {
                            //正涵身长度赋值为最大正涵身
                            positiveBodyLength = positiveBodyMaxValue;

                            //判断正涵身长度为最大正涵身值时是否还有余长
                            if (positiveBodyTotalLength % positiveBodyMaxValue != 0)
                            {
                                //将余长加到左斜涵长上加入集合
                                obliqueCulminationLength = leftObliqueCulminationLengthMinValue + ((positiveBodyTotalLength % positiveBodyMaxValue) / 2);
                                culvertLengthList.Add(obliqueCulminationLength);

                                //将正涵身长加入到集合
                                culvertLengthList.Add(positiveBodyLength);

                                //将余长加到右斜涵长上加入集合
                                obliqueCulminationLength = rightObliqueCulminationLengthMinValue + ((positiveBodyTotalLength % positiveBodyMaxValue) / 2);
                                culvertLengthList.Add(obliqueCulminationLength);

                                return culvertLengthList;
                            }
                            //没有余长，此时按正涵身长度最大值计算，加入集合进行返回
                            culvertLengthList.Add(leftObliqueCulminationLengthMinValue);
                            culvertLengthList.Add(positiveBodyLength);
                            culvertLengthList.Add(rightObliqueCulminationLengthMinValue);
                            return culvertLengthList;
                        }
                        else
                        {
                            //如果余数不够按最大正涵身长度算时就加到最小正涵身值上，然后加入到集合返回
                            culvertLengthList.Add(leftObliqueCulminationLengthMinValue);
                            culvertLengthList.Add(positiveBodyTotalLength);
                            culvertLengthList.Add(rightObliqueCulminationLengthMinValue);
                            return culvertLengthList;
                        }
                    }
                    else
                    {
                        //将一边的斜涵长加入到集合中
                        culvertLengthList.Add(leftObliqueCulminationLengthMinValue);

                        //将每个正涵身都加入到集合当中
                        for (int i = 0; i < positiveBodyCount; i++)
                        {
                            culvertLengthList.Add(positiveBodyMinValue);
                        }

                        //判断正涵身总长除以最小正涵身值时是否还有余长
                        if (positiveBodyTotalLength % positiveBodyMinValue == 0)
                        {
                            //没有余长就进行添加斜涵长到集合进行返回
                            culvertLengthList.Add(rightObliqueCulminationLengthMinValue);
                            return culvertLengthList;
                        }
                        else
                        {
                            //定义一个变量接受余数，来判断循环次数
                            int num = (int)(positiveBodyTotalLength % positiveBodyMinValue);

                            //定义一个double类型余数，来接受小数点
                            double remainder = positiveBodyTotalLength % positiveBodyMinValue;

                            //定义一个变量来作为集合的下标
                            int listIndex = culvertLengthList.Count - 1;

                            //如果余数小于1时，直接将余数加入到集合最后一个正涵身长度中
                            if (num < 1)
                            {
                                culvertLengthList[listIndex] = culvertLengthList[listIndex] + remainder;
                            }

                            //通过余数来判断需要循环几次来从后依次改变集合中的正涵身长度
                            for (int i = num; i > 0; i--)
                            {
                                culvertLengthList[listIndex] = culvertLengthList[listIndex] + 1;
                                remainder--;

                                //判断余数是否还剩够1个，如果不够就将小数加到最后一个正涵身上
                                if (remainder < 1)
                                {
                                    culvertLengthList[culvertLengthList.Count - 1] = culvertLengthList[culvertLengthList.Count - 1] + remainder;
                                }

                                listIndex--;

                                //判断是否为集合第一个元素
                                if (listIndex == 0)
                                {
                                    listIndex = culvertLengthList.Count - 1;
                                }
                            }

                            //最后将斜涵长加入到集合中进行返回
                            culvertLengthList.Add(rightObliqueCulminationLengthMinValue);
                            return culvertLengthList;
                        }
                    }
                }
            }
            else
            {
                if (totalCulvertLength - (leftObliqueCulminationLengthRecommendValue + rightObliqueCulminationLengthRecommendValue) < positiveBodyMinValue)
                {
                    //此时没有正涵身，所以用总涵长求两个斜涵长的值
                    obliqueCulminationLength = totalCulvertLength / 2;

                    //将两个斜涵长添加到集合中进行返回
                    culvertLengthList.Add(obliqueCulminationLength);
                    culvertLengthList.Add(obliqueCulminationLength);
                    return culvertLengthList;
                }
                else
                {
                    //求出正涵身的总长度
                    positiveBodyTotalLength = totalCulvertLength - (leftObliqueCulminationLengthRecommendValue + rightObliqueCulminationLengthRecommendValue);

                    //定义正涵身的个数变量
                    int positiveBodyCount = (int)(positiveBodyTotalLength / positiveBodyMinValue);

                    //判断正涵身的个数是否只有一个
                    if (positiveBodyCount == 1)
                    {
                        //判断正涵身按最小正涵身值算时多余长度是否够按最大正涵身长度计算
                        if (positiveBodyTotalLength % positiveBodyMinValue > (positiveBodyMaxValue - positiveBodyMinValue))
                        {
                            //正涵身长度赋值为最大正涵身
                            positiveBodyLength = positiveBodyMaxValue;

                            //判断正涵身长度为最大正涵身值时是否还有余长
                            if (positiveBodyTotalLength % positiveBodyMaxValue != 0)
                            {
                                //将余长加到左斜涵长上
                                obliqueCulminationLength = leftObliqueCulminationLengthRecommendValue + ((positiveBodyTotalLength % positiveBodyMaxValue) / 2);
                                culvertLengthList.Add(obliqueCulminationLength);

                                //将正涵身长加入到集合
                                culvertLengthList.Add(positiveBodyLength);

                                //将余长加到右斜涵长上
                                obliqueCulminationLength = rightObliqueCulminationLengthRecommendValue + ((positiveBodyTotalLength % positiveBodyMaxValue) / 2);
                                culvertLengthList.Add(obliqueCulminationLength);
                                return culvertLengthList;
                            }
                            //没有余长，此时按正涵身长度最大值计算，加入集合进行返回
                            culvertLengthList.Add(leftObliqueCulminationLengthRecommendValue);
                            culvertLengthList.Add(positiveBodyLength);
                            culvertLengthList.Add(rightObliqueCulminationLengthRecommendValue);
                            return culvertLengthList;
                        }
                        else
                        {
                            //如果余数不够按最大正涵身长度算时就加到最小正涵身值上，然后加入到集合返回
                            culvertLengthList.Add(leftObliqueCulminationLengthRecommendValue);
                            culvertLengthList.Add(positiveBodyTotalLength);
                            culvertLengthList.Add(rightObliqueCulminationLengthRecommendValue);
                            return culvertLengthList;
                        }
                    }
                    else
                    {
                        //将一边的斜涵长加入到集合中
                        culvertLengthList.Add(leftObliqueCulminationLengthRecommendValue);

                        //将每个正涵身都加入到集合当中
                        for (int i = 0; i < positiveBodyCount; i++)
                        {
                            culvertLengthList.Add(positiveBodyMinValue);
                        }

                        //判断正涵身总长除以最小正涵身值时是否还有余长
                        if (positiveBodyTotalLength % positiveBodyMinValue == 0)
                        {
                            //没有余长就进行添加斜涵长到集合进行返回
                            culvertLengthList.Add(rightObliqueCulminationLengthRecommendValue);
                            return culvertLengthList;
                        }
                        else
                        {
                            //定义一个变量接受余数，来判断循环次数
                            int num = (int)(positiveBodyTotalLength % positiveBodyMinValue);

                            //定义一个double类型余数，来接受小数点
                            double remainder = positiveBodyTotalLength % positiveBodyMinValue;

                            //定义一个变量来作为集合的下标
                            int listIndex = culvertLengthList.Count - 1;

                            //如果余数小于1时，直接将余数加入到集合最后一个正涵身长度中
                            if (num < 1)
                            {
                                culvertLengthList[listIndex] = culvertLengthList[listIndex] + remainder;
                            }

                            //通过余数来判断需要循环几次来从后依次改变集合中的正涵身长度
                            for (int i = num; i > 0; i--)
                            {
                                culvertLengthList[listIndex] = culvertLengthList[listIndex] + 1;
                                remainder--;

                                //判断余数是否还剩够1个，如果不够就将小数加到最后一个正涵身上
                                if (remainder < 1)
                                {
                                    culvertLengthList[culvertLengthList.Count - 1] = culvertLengthList[culvertLengthList.Count - 1] + remainder;
                                }

                                listIndex--;

                                //判断是否为集合第一个元素
                                if (listIndex == 0)
                                {
                                    listIndex = culvertLengthList.Count - 1;
                                }
                            }

                            //最后将斜涵长加入到集合中进行返回
                            culvertLengthList.Add(rightObliqueCulminationLengthRecommendValue);
                            return culvertLengthList;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 提取沉降缝节点
        /// </summary>
        /// <returns>节点集合</returns>
        internal List<double> drawSettlementJoint(DataGridView dgv)
        {
            //定义一个接受表格数据的集合
            List<string> settlementJoints = new List<string>();

            //定义一个沉降缝节点集合
            List<double> nodes = new List<double>();

            //定义一个分段长度集合
            List<double> segmentLengths = new List<double>();

            //获取到表格的总行数
            int count = dgv.RowCount;

            //循环将沉降缝节点加入到集合中
            for (int i = 0; i < count; i++)
            {
                string settlementJoint = dgv.Rows[i].Cells[2].Value.ToString().Trim();
                settlementJoints.Add(settlementJoint);
            }

            //循环将分段长度填入集合中
            for (int i = 1; i < count - 1; i++)
            {
                string segmentLength = dgv.Rows[i].Cells[1].Value.ToString().Trim();
                segmentLengths.Add(Convert.ToDouble(segmentLength));
            }

            //定义一个变量接受最近一次的节点下标位置
            int num = 0;

            //通过循环来循环每个沉降缝的数据
            for (int i = 1; i < settlementJoints.Count - 1; i++)
            {
                //判断是否有节点
                if (settlementJoints[i].Equals("True"))
                {
                    //定义一个接受分段长度和的变量
                    double sum = 0;

                    //通过循环来将沉降缝改变后的分段长度计算出
                    for (int j = num; j < i; j++)
                    {
                        sum = sum + segmentLengths[j];
                    }

                    //将改变后的分段长度加入到节点集合中
                    nodes.Add(sum / 100);

                    //更新最近节点的下标
                    num = i;
                }
            }

            //判断最近节点之后是否还有分段长度
            if (num != settlementJoints.Count - 1)
            {
                //通过循环将剩余的所有分段长度加入到节点集合中
                for (int i = num + 1; i < settlementJoints.Count - 1; i++)
                {
                    nodes.Add(segmentLengths[i - 1] / 100);
                }
            }

            //返回节点集合
            return nodes;
        }

    }
}
